﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;

namespace CommonLib.Log
{
    public class EfficientLogger : IEqualityComparer<EfficientLogger>
    {
        private readonly object _writeLockObj = new object();

        private FileStream _fs;

        private string _logPath = string.Empty;
        public string LogPath
        {
            get { return _logPath; }
        }

        private string _filePath = string.Empty;

        private string _deviceName = string.Empty;
        public string DeviceName
        {
            get { return _deviceName; }
        }

        private int _type = -1;
        public int Type
        {
            get { return _type; }
        }

        private string _date = string.Empty;
        public string Date
        {
            get { return _date; }
        }

        public EfficientLogger(string logDate, int logType, string deviceName, string logPath)
        {
            this._date = logDate;
            this._type = logType;
            this._deviceName = deviceName;
            this._logPath = logPath;
        }

        public void InitLogFile()
        {
            if (_fs == null)
            {
                if (!Directory.Exists(_logPath))
                {
                    Directory.CreateDirectory(_logPath);
                }
                _filePath = "{0}\\{1}{2}.txt".FormatWith(_logPath, DateTime.Now.ToString("yyyy-MM-dd"), GetLogTypeFileSort(_type));
                _fs = new FileStream(_filePath, FileMode.Append, FileAccess.Write);
            }
        }

        public void WriteLogFile(string content)
        {
            string curDate = DateTime.Now.ToString("yyyy-MM-dd");

            lock (_writeLockObj)
            {
                if (_date != curDate)
                {
                    Logger.getInstance().WriteToLog((int)LogType.I, "WriteToLog => 设备[{0}]文件日期由[{1}]变为[{2}]".FormatWith(_deviceName, _date, curDate), ConfigurationManager.AppSettings["CommonLog"].ToString());

                    CloseLogFile();

                    _date = curDate;
                    _logPath = string.Format("{0}{1}\\{2}", ConfigurationManager.AppSettings["CommonLog"].ToString(), DateTime.Now.ToString("yyyyMMdd"), _deviceName);
                    InitLogFile();
                }

                try
                {
                    string time = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss.fff] ");
                    content = time + content + Environment.NewLine;
                    char[] charDataValue = content.ToCharArray();
                    System.Text.Encoder ec = System.Text.Encoding.UTF8.GetEncoder();
                    int byteCount = ec.GetByteCount(charDataValue, 0, charDataValue.Length, true);
                    byte[] byteDataValue = new byte[byteCount];
                    ec.GetBytes(charDataValue, 0, charDataValue.Length, byteDataValue, 0, true);
                    _fs.Write(byteDataValue, 0, byteDataValue.Length);
                    _fs.Flush();
                }
                catch (Exception ex)
                {
                    if (_fs != null)
                    {
                        _fs.Close();
                        _fs = null;
                    }

                    Logger.getInstance().WriteToLog((int)LogType.E, "WriteToLog => [{0}][{1}]".FormatWith(content, ex.Message), _logPath);
                }
            }
        }

        public void CloseLogFile()
        {
            if (_fs != null)
            {
                _fs.Close();
                _fs = null;
            }
        }

        public string GetLogTypeFileSort(int logType)
        {
            string fileSort = string.Empty;
            switch (logType)
            {
                case (int)LogType.E: //错误 日志
                    fileSort = "Error";
                    break;
                case (int)LogType.SQL: //执行SQL语句
                    fileSort = "SQL";
                    break;
                default:
                    fileSort = "Info";
                    break;
            }
            return fileSort;
        }

        #region IEqualityComparer接口方法
        public bool Equals(EfficientLogger x, EfficientLogger y)
        {
            return x.DeviceName == y.DeviceName && x.Type == y.Type;
        }

        public int GetHashCode(EfficientLogger obj)
        {
            return obj.ToString().GetHashCode();
        }
        #endregion
    }
}
